/******************************************************************************
 * * modem_adp.c - implementation of modem adaptor
 *
 * *(C) Copyright 2019 Asr International Ltd.
 * * All Rights Reserved
 * ******************************************************************************/
#include "lv_watch.h"

#if USE_LV_WATCH_MODEM_ADAPTOR != 0
#include "mmi_modem_adaptor_nw.h"
#include "mmi_modem_adaptor_call.h"

/*********************
*      INCLUDES
*********************/
#include <stdio.h>

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/

/**********************
 *  STATIC VARIABLES
 **********************/

MMI_MODEM_SIM_ID modem_sim_id = MMI_MODEM_SIM_1;

extern void setMasterSimID(int simID);
extern INT32 CM_SetMasterSimID(CMSimID simID, SwitchSimDoneCb cb);

MMI_MODEM_SIM_ID watch_modem_get_sim_id(void)
{
    return modem_sim_id;
}

void watch_modem_set_sim_id(MMI_MODEM_SIM_ID SimId)
{
    printf("%s: SimId: %d\n", __FUNCTION__, SimId);
    modem_sim_id = SimId;

    CMSimID CmSimId = (MMI_MODEM_SIM_1 == SimId) ? CM_SIM_0 : CM_SIM_1;
    setMasterSimID(CmSimId);
}

void watch_modem_switch_to_sim(MMI_MODEM_SIM_ID SimTo)
{
    if(SimTo == modem_sim_id) {
        return;
    }
    printf("%s: SimTo: %d\n", __FUNCTION__, SimTo);

    //set apn mode
    MMI_ModemAdp_Set_Apn_Mode(SimTo);

    //set master sim id
    CMSimID cm_sim_id = (MMI_MODEM_SIM_1 == SimTo) ? CM_SIM_0 : CM_SIM_1;
    CM_SetMasterSimID(cm_sim_id, NULL);

    //power off/on
    MMI_Modem_Power_Off_Req(modem_sim_id, MMI_MODEM_POWER_OFF);
    MMI_Modem_Power_Up_Req(SimTo);
    modem_sim_id = SimTo;
}

void watch_modem_set_connection_switch(BOOL OnOff)
{
    MMI_ModemAdp_Set_Connection_Switch(OnOff);
}

BOOL watch_modem_get_connection_switch(void)
{
    return MMI_ModemAdp_Get_Connection_Switch();
}

void watch_modem_set_data_roaming(BOOL OnOff)
{
    MMI_ModemAdp_Set_Data_Roaming(OnOff);
}

BOOL watch_modem_get_data_roaming(void)
{
    return MMI_ModemAdp_Get_Data_Roaming();
}

int watch_modem_get_default_apn_name(char *Name, int NameLen)
{
    return MMI_ModemAdp_Get_Default_Apn_Name(Name, NameLen);
}

int watch_modem_get_default_ip_type(void)
{
    return MMI_ModemAdp_Get_Default_Ip_Type();
}

void watch_modem_set_apn_info(MMI_Modem_Apn_Info_t *ApnInfo)
{
    MMI_ModemAdp_Set_Apn_Info(ApnInfo);
}

void watch_modem_reset_apn(void)
{
    MMI_ModemAdp_Reset_Apn();
}

void watch_modem_config_apn(char *Apn, UINT8 IpType)
{
    MMI_ModemAdp_Config_Apn(Apn, IpType);
}

void watch_modem_open_volte(void)
{
    MMI_ModemAdp_Open_Volte_Req(modem_sim_id);
}

uint8_t get_wifi(void)
{
    /*wifi: 0/1/2/3/4*/
    uint8_t wifi = 4;

    return wifi;
}

void watch_modem_power_up_req(void)
{
    MMI_Modem_Power_Up_Req(modem_sim_id);
}

void watch_modem_power_off_req(void)
{
    MMI_Modem_Power_Off_Req(modem_sim_id, MMI_MODEM_POWER_OFF);
}

void watch_modem_get_imei_req(char * imei)
{
    MMI_Modem_Query_Imei_Req(modem_sim_id, imei);
}

void watch_modem_get_baseband_ver_req(char * baseband_ver)
{
    MMI_Modem_Call_Query_Baseband_Version(modem_sim_id,baseband_ver);
}

void  watch_modem_get_imsi_req(char * imsi)
{
    MMI_Modem_Query_Imsi_Req(modem_sim_id, imsi);
}

void  watch_modem_sim_soft_reset_req(void)
{
    MMI_Modem_Sim_Soft_Reset_Req(modem_sim_id);
}

uint8_t watch_modem_sim_present_check_req(void)
{
    uint8_t simpresent = MMI_Modem_Sim_Present_Check_Req(modem_sim_id);
//    printf("%s sim present %d\n", __FUNCTION__, simpresent);
    return(simpresent);
}

MMI_MODEM_SIGNAL_BAR watch_modem_get_signal_bar_req(void)
{
    return(MMI_Modem_Get_Signal_Bar_Req(modem_sim_id));
}

uint8_t watch_modem_voice_registration_state_req(void)
{
    uint8_t state = MMI_Modem_Voice_Registration_State_Req(modem_sim_id);
    printf("%s: state: %d\n", __FUNCTION__, state);
    return(state);
}

void watch_modem_get_operator_req(MMI_MODEM_PLMN_RAT * Rat)
{
    char operator[MMI_MAX_PLMN_NAME_LEN + 1];

    MMI_Modem_Get_Operator_Req(modem_sim_id, operator, Rat);
}

uint8_t watch_modem_get_ims_reg_state_req(void)
{
    return MMI_Modem_Get_Ims_Reg_State_Req(modem_sim_id);
}

uint8_t watch_modem_get_gsm_reg_state_req(void)
{
    return MMI_Modem_Get_Gsm_Reg_State_Req(modem_sim_id);
}

uint8_t watch_modem_get_umts_reg_state_req(void)
{
    return MMI_Modem_Get_Umts_Reg_State_Req(modem_sim_id);
}

void watch_modem_call_request_dial(char * number, MMI_MODEM_CALL_SERVICE_TYPE servicetype)
{
    MMI_Modem_Call_Request_Dial(modem_sim_id, number, servicetype);
}

void watch_modem_call_request_hangup(int32_t index)
{
    MMI_Modem_Call_Request_Hangup(modem_sim_id, index);
}

void watch_modem_call_request_hangup_foreground_resume_background(void)
{
    MMI_Modem_Call_Request_Hangup_Foreground_Resume_Background(modem_sim_id);
}

void watch_modem_call_request_switch_waiting_or_hold_and_active(void)
{
    MMI_Modem_Call_Request_Switch_Waiting_Or_Holding_And_Active(modem_sim_id);
}

void watch_modem_call_request_udub(void)
{
    MMI_Modem_Call_Request_Udub(modem_sim_id);
}

void watch_modem_call_request_answer(void)
{
    MMI_Modem_Call_Request_Answer(modem_sim_id);
}

void watch_modem_call_response_clip_auto(int32_t index, MMI_Modem_Call_Response_Clip_t *clip)
{
    MMI_Modem_Call_Response_Clip(modem_sim_id, index,clip);
}

void watch_modem_signal_bar_ind(MMI_MODEM_SIGNAL_BAR Bar)
{
    // todo: status_and_setting.c
}
void watch_modem_sim_status_ind(MMI_Modem_Sim_Status_t * SimStatus)
{
    // todo:
}

void watch_modem_read_sms_detail_on_sim_cnf(MMI_Modem_Read_Sms_Detail_On_Sim_Cnf_t * pReadSmsCnf)
{
    // todo:
}

void watch_modem_send_sms_cnf(MMI_Modem_Send_Sms_Cnf_t * pSendSmsCnf)
{
    //
}

void watch_modem_operator_ind(MMI_MODEM_PLMN_RAT Rat)
{
    //todo: status_and_setting.c
    printf("%s, rat %d\n", __FUNCTION__, Rat);
}

void watch_modem_rep_new_sms_ind(MMI_Modem_Report_New_Sms_Ind_t * pRepNewSms)
{
    // todo:
}

void watch_modem_screen_state_req(int state)
{
    MMI_ModemAdp_Screen_State_Req(state);
}

/**
 * query current call active status
 * param (in) void
 * return  bool
 */
bool watch_modem_call_get_call_active_status(void)
{
    return(MMI_ModemAdp_Call_Get_Call_Active_Status());
}

/**
 * Request modem adpter to try PIN code
 * param (in) MMI_MODEM_PIN_TYPE pintype
 *         char *pin
 * return  uint8_t :Retry Left: MMI_MODEM_PIN_CHECK_OK when check OK
 */
uint8_t watch_modem_request_enter_sim_pin(MMI_MODEM_PIN_TYPE pintype,char *pin)
{
    (void)pintype;

    return(MMI_Modem_Try_Pin_Req(modem_sim_id, pin));
}

/**
 * Request modem adpter to change PIN code
 * param (in)   MMI_MODEM_PIN_TYPE pintype
 *          char *pin,char *oldpin
 * return  uint8_t :Retry Left: MMI_MODEM_PIN_CHECK_OK when check OK
 */
uint8_t watch_modem_change_sim_pin(MMI_MODEM_PIN_TYPE pintype,char *pin,char *oldpin)
{
    (void)pintype;

    return(MMI_Modem_Change_Pin_Req(modem_sim_id, pin, oldpin));
}

/**
 * Query PIN lock information
 * param (in)   MMI_MODEM_PIN_TYPE pintype,
 *              pinlockinfo: MMI_Modem_Query_Pin_Lock_Info_t *,return the pin lock info
 * return  void
 */
void watch_modem_query_pin_lock_info(MMI_MODEM_PIN_TYPE pintype,MMI_Modem_Query_Pin_Lock_Info_t *pinlockinfo)
{
    (void)pintype;

    MMI_Modem_Pin_Lock_t * PinLockQuery = NULL;

    if(NULL == pinlockinfo)
    {
        LV_ASSERT_MEM(pinlockinfo);
    }

    PinLockQuery = (MMI_Modem_Pin_Lock_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Pin_Lock_t));

    Hal_Mem_Set(PinLockQuery,0,sizeof(MMI_Modem_Pin_Lock_t));

    PinLockQuery->SimId = modem_sim_id;

    PinLockQuery->PinType = MMI_MODEM_PIN1;

    MMI_Modem_Query_Facility_Pin_Lock(PinLockQuery);

    pinlockinfo->PinEnable = PinLockQuery->PinEnable;
    pinlockinfo->RetriesLeft = PinLockQuery->RetriesLeft;

    Hal_Mem_Free(PinLockQuery);
}

/**
 * Enable or disable PIN lock
 * param (in)   MMI_MODEM_PIN_TYPE pintype
 *             pinenable:uint8_t 1 is Enable,0 is DISABLE
 *            char *pin
 * return  uint8_t :Result: MMI_MODEM_PIN_CHECK_OK means set OK ,otherwise means the retry-left times
 */
uint8_t watch_modem_enable_or_disable_pin_lock(MMI_MODEM_PIN_TYPE pintype,uint8_t pinenable,char *pin)
{
    (void)pintype;

    uint8_t              Result;
    MMI_Modem_Pin_Lock_t * PinLockSet = (MMI_Modem_Pin_Lock_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Pin_Lock_t));

    Hal_Mem_Set(PinLockSet,0,sizeof(MMI_Modem_Pin_Lock_t));

    PinLockSet->SimId = modem_sim_id;

    PinLockSet->PinType = MMI_MODEM_PIN1;

    PinLockSet->PinEnable = pinenable;

    MMI_Modem_Enable_Pin_Lock(PinLockSet, pin);

    Result = PinLockSet->RetriesLeft;

    Hal_Mem_Free(PinLockSet);

    return Result;
}

/**
 * set band information for engineer mode
 * param (in) bandmode: uint8_t
 * param (in) gsmband: uint8_t
 * param (in) ltebandh: uint16_t
 * param (in) ltebandl: uint32_t
 * return  void
 */
void watch_modem_set_band_req(uint8_t bandmode, uint8_t gsmband, uint16_t ltebandh, uint32_t ltebandl)
{
    MMI_Modem_Set_Band_Req_t * pSetBandReq = NULL;

    pSetBandReq = (MMI_Modem_Set_Band_Req_t *)Hal_Mem_Alloc(sizeof(MMI_Modem_Set_Band_Req_t));
    Hal_Mem_Set(pSetBandReq, 0, sizeof(MMI_Modem_Set_Band_Req_t));

    pSetBandReq->mode = bandmode;
    pSetBandReq->gsmBand = gsmband;
    pSetBandReq->lteBandH = ltebandh;
    pSetBandReq->lteBandL = ltebandl;

    MMI_Modem_Set_Band_Req(pSetBandReq);
}

/**
 * set volte state
 * param (in) state: uint8_t
 * return  void
 */
void watch_modem_set_volte_state_req(uint8_t state)
{
    MMI_Modem_Volte_State_Req(modem_sim_id, state);
}

/**
 * Get the status of SIM phonebook
 * param (in) void
 * return  void
 */
void watch_modem_get_phonebook_status_req(void)
{
    MMI_Modem_Get_Phonebook_Status_Req(modem_sim_id);
}

/**
 * Write the contact into SIM phonebook
 * param (in) index: if MMI_MODEM_CONTACT_INDEX_INVALID, add the new contact into sim phonebook.
 *                   otherwise delete the contact with the index from sim phonebook,
 *                   name and number are omit.
 * param (in) name: char *, string,
 *                  support empty name,
 *                  max 6 characters if including one chinese character at lest,
 *                  otherwise 14 charaters for example "1234567890abcd".
 * param (in) number: char *, string,
 *                    not support empty number,
 *                    max 20 characters
 * return  bool: parameter error if false, otherwise true
 */
bool watch_modem_write_phonebook_req(uint16_t index, char * name, char * number)
{
    if(MMI_MODEM_CONTACT_INDEX_INVALID == index) {
        // add the new contact info sim phonebook
        if((NULL == number)
           || (number && (0 == strlen(number)))) {
            printf("%s: not support empty number\n", __FUNCTION__);
            return false;
        } else if (MMI_MODEM_MAX_NUMBER_LEN <= strlen(number)) {
            printf("%s: longer number %s than %d\n", __FUNCTION__, number, MMI_MODEM_MAX_NUMBER_LEN);
            return false;
        } else if (name && (MMI_MODEM_MAX_NAME_LEN <= strlen(name))) {
            printf("%s: longer name %s than %d\n", __FUNCTION__, name, MMI_MODEM_MAX_NAME_LEN);
            return false;
        }
    }

    MMI_Modem_Contact * Contact = (MMI_Modem_Contact *)Hal_Mem_Alloc(sizeof(MMI_Modem_Contact));
    if(NULL == Contact) {
        printf("%s: memory error\n", __FUNCTION__);
        return false;
    }

    if(MMI_MODEM_CONTACT_INDEX_INVALID == index) {
        if(name) {
            Hal_Mem_Copy(Contact->Name, name, strlen(name) + 1);
        } else {
            Contact->Name[0] = '\0';
        }
        Hal_Mem_Copy(Contact->Number, number, strlen(number) + 1);
        Contact->Index = MMI_MODEM_CONTACT_INDEX_INVALID;
    } else {
        // delete the contact with index from sim phonebook
        Contact->Index = index;
    }
    MMI_Modem_Write_Phonebook_Req(modem_sim_id, Contact);

    return true;
}

/**
 * Read the contacts from SIM phonebook
 * param (in) start_index: the starting index in SIM phonebook for the contact to read
 * param (in) end_index: the end index in SIM phonebook for the contact to read
 * return  bool: parameter error if false, otherwise true
 */
bool watch_modem_read_phonebook_req(uint16_t start_index, uint16_t end_index)
{
    if(end_index < start_index) {
        printf("%s: end_index %d < start_index %d\n", __FUNCTION__, end_index, start_index);
        return false;
    }

    MMI_Modem_Read_Phonebook_Req(modem_sim_id, end_index - start_index + 1, start_index);

    return true;
}

/**
 * power up SIMx confrom
 * param (in) simId: MMI_MODEM_SIM_ID
 * return  void
 */
void MMI_Modem_Power_Up_Cnf(MMI_MODEM_SIM_ID simId)
{
    if(0  == Hal_Pm_Get_State()) return;

    mmi_msg_power_up_cnf_t * msg;

    msg = (mmi_msg_power_up_cnf_t *)lv_mem_alloc(sizeof(mmi_msg_power_up_cnf_t));

    msg->header.MsgId = MMI_MODEM_POWER_UP_CNF;
    msg->simid = simId;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * power off SIMx confrom
 * param (in) simId: MMI_MODEM_SIM_ID
 * return  void
 */
void MMI_Modem_Power_Off_Cnf(MMI_MODEM_SIM_ID simId)
{
    if(0 == Hal_Pm_Get_State()) return;

    mmi_msg_power_off_cnf_t * msg;

    msg = (mmi_msg_power_off_cnf_t *)lv_mem_alloc(sizeof(mmi_msg_power_off_cnf_t));

    msg->header.MsgId = MMI_MODEM_POWER_OFF_CNF;
    msg->simid = simId;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 *
 * This message is sent to the calling mobile station
 *  to response that the get the current calls command
 * param simId:  MMI_MODEM_SIM_ID
 * param index:  Connection index
 * return  void
 */
void MMI_Modem_Call_Rsp_Get_Current_Calls(MMI_Modem_Call_Rsp_Get_Current_Calls_t * calls)
{
    if(0 == Hal_Pm_Get_State()) {
        Hal_Pm_WakeUp();
    } else {
        watch_wakeup_lcd(false);
    }

    mmi_msg_call_response_get_cur_calls_t * msg;

    msg = (mmi_msg_call_response_get_cur_calls_t *)lv_mem_alloc(sizeof(mmi_msg_call_response_get_cur_calls_t));

    msg->header.MsgId = MMI_MODEM_CALL_RESPONSE_GET_CUR_CALLS;
    msg->calls = calls;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 *
 * This message is sent to the calling mobile station
 *  to indicate that the call is originating. (after ATD <number>;)
 * param simId:  MMI_MODEM_SIM_ID
 * param index:  Connection index
 * return  void
 */
void MMI_Modem_Call_Response_Originating(MMI_MODEM_SIM_ID simId, int32_t index)
{
    if(0 == Hal_Pm_Get_State()) {
        Hal_Pm_WakeUp();
    } else {
        watch_wakeup_lcd(false);
    }

    mmi_msg_call_response_originating_t * msg;

    msg = (mmi_msg_call_response_originating_t *)lv_mem_alloc(sizeof(mmi_msg_call_response_originating_t));

    msg->header.MsgId = MMI_MODEM_CALL_RESPONSE_ORIGINATING;
    msg->simid = simId;
    msg->index = index;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 *
 * This message is sent to the calling mobile station
 *  to indicate that the called user alerting has been initiated.
 * param simId:  MMI_MODEM_SIM_ID
 * param index:  Connection index
 * return  void
 */
void MMI_Modem_Call_Response_Alerting(MMI_MODEM_SIM_ID simId, int32_t index)
{
    if(0 == Hal_Pm_Get_State()) {
        Hal_Pm_WakeUp();
    } else {
        watch_wakeup_lcd(false);
    }

    mmi_msg_call_response_alerting_t * msg;

    msg = (mmi_msg_call_response_alerting_t *)lv_mem_alloc(sizeof(mmi_msg_call_response_alerting_t));

    msg->header.MsgId = MMI_MODEM_CALL_RESPONSE_ALERTING;
    msg->simid = simId;
    msg->index = index;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 *
 * This message is sent to the called mobile station
 *  to indicate an incoming call (voice, data or fax). (RING)
 * param simId:  MMI_MODEM_SIM_ID
 * param index:  Connection index
 * return  void
 */
void MMI_Modem_Call_Response_Ring(MMI_MODEM_SIM_ID simId, int32_t index)
{
    if(0 == Hal_Pm_Get_State()) {
        watch_disable_wakeup_lcd();
        Hal_Pm_WakeUp();
    }

    mmi_msg_call_response_ring_t * msg;

    msg = (mmi_msg_call_response_ring_t *)lv_mem_alloc(sizeof(mmi_msg_call_response_ring_t));

    msg->header.MsgId = MMI_MODEM_CALL_RESPONSE_RING;
    msg->simid = simId;
    msg->index = index;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * This message is sent to the calling/called mobile station
 *  to indication that the call is connected.
 * param simId:  MMI_MODEM_SIM_ID
 * param index:  Connection index
 * return  void
 */
void MMI_Modem_Call_Response_Connect(MMI_MODEM_SIM_ID simId, int32_t index)
{
    if(0 == Hal_Pm_Get_State()) return;

    mmi_msg_call_response_connect_t * msg;

    msg = (mmi_msg_call_response_connect_t *)lv_mem_alloc(sizeof(mmi_msg_call_response_connect_t));

    msg->header.MsgId = MMI_MODEM_CALL_RESPONSE_CONNECT;
    msg->simid = simId;
    msg->index = index;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * This message is sent to the calling/called mobile station
 *  to indication that the call is disconnected.
 * param simId:  MMI_MODEM_SIM_ID
 * param index:  Connection index
 * return  void
 */
void MMI_Modem_Call_Response_Disconnect(MMI_MODEM_SIM_ID simId, int32_t index)
{
    if(0 == Hal_Pm_Get_State()) {
        Hal_Pm_WakeUp();
    } else {
        if(g_ModemCallMng.DualCallPresent) {
            watch_wakeup_lcd(false);
        }
    }

    mmi_msg_call_response_disconnect_t * msg;

    msg = (mmi_msg_call_response_disconnect_t *)lv_mem_alloc(sizeof(mmi_msg_call_response_disconnect_t));

    msg->header.MsgId = MMI_MODEM_CALL_RESPONSE_DISCONNECT;
    msg->simid = simId;
    msg->index = index;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * Indicates a disconnect for Call Clearing or a Call Failed for an outgoing call. (NO CARRIER)
 * param simId:  MMI_MODEM_SIM_ID
 * param index:  Connection index
 * param isNoCarrier:  uint8_t
 * return  void
 */
void MMI_Modem_Call_Response_No_Carrier(MMI_MODEM_SIM_ID simId, int32_t index, uint8_t isNoCarrier)
{
    if(0 == Hal_Pm_Get_State()) {
        Hal_Pm_WakeUp();
    }

    mmi_msg_call_response_no_carrier_t * msg;

    msg = (mmi_msg_call_response_no_carrier_t *)lv_mem_alloc(sizeof(mmi_msg_call_response_no_carrier_t));

    msg->header.MsgId = MMI_MODEM_CALL_RESPONSE_NO_CARRIER;
    msg->simid = simId;
    msg->index = index;
    msg->isNoCarrier = isNoCarrier;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * Indicates ATD OK or cme error for an outgoing call.
 * param simId:  MMI_MODEM_SIM_ID
 * param isNoCarrier:  uint8_t,0 is OK,1 is cme error
 * return  void
 */
void MMI_Modem_Call_Response_Dial(MMI_MODEM_SIM_ID simId, uint8_t isOk)
{
    if(0 == Hal_Pm_Get_State()) {
        Hal_Pm_WakeUp();
    } else {
        watch_wakeup_lcd(false);
    }

    mmi_msg_call_response_dial_t * msg;

    msg = (mmi_msg_call_response_dial_t *)lv_mem_alloc(sizeof(mmi_msg_call_response_dial_t));

    msg->header.MsgId = MMI_MODEM_CALL_RESPONSE_DIAL;
    msg->simid = simId;
    msg->isOk = isOk;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * Indicates the calling line identity of the calling party after every RING/+CRING. (+CLIP:)
 * +CLIP: <number>,<type>
 *
 * param simId:  MMI_MODEM_SIM_ID
 * param index:  Connection index
 * param clip:  MMI_MODEM_CALL_RESPONSE_CLIP *
 * return  void
 */
void MMI_Modem_Call_Response_Clip(MMI_MODEM_SIM_ID simId, int32_t index,
                                  MMI_Modem_Call_Response_Clip_t * clip)
{
    mmi_msg_call_response_clip_t * msg;

    msg = (mmi_msg_call_response_clip_t *)lv_mem_alloc(sizeof(mmi_msg_call_response_clip_t));

    msg->header.MsgId = MMI_MODEM_CALL_RESPONSE_CLIP;
    msg->simid = simId;
    msg->index = index;
    msg->clip  = clip;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * Indicates Call Waiting (CW) information (when enabled) for an incoming call. (+CCWA:)
 * +CCWA: <number>,<type>,<class>,[<alpha>][,<CLI validity>[,<subaddr>,<satype>[,<priority>]]]
 *
 * param simId:  MMI_MODEM_SIM_ID
 * param index:  Connection index
 * param ccwa:  MMI_MODEM_CALL_RESPONSE_CCWA *
 * return  void
 */
void MMI_Modem_Call_Response_Ccwa(MMI_MODEM_SIM_ID simId, int32_t index,
                                  MMI_Modem_Call_Response_Ccwa_t * ccwa)
{
    if(0 == Hal_Pm_Get_State()) {
        watch_disable_wakeup_lcd();
        Hal_Pm_WakeUp();
    }
    mmi_msg_call_response_ccwa_t * msg;

    msg = (mmi_msg_call_response_ccwa_t *)lv_mem_alloc(sizeof(mmi_msg_call_response_ccwa_t));

    msg->header.MsgId = MMI_MODEM_CALL_RESPONSE_CCWA;
    msg->simid = simId;
    msg->index = index;
    msg->ccwa  = ccwa;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * Indicats the call state is changed
 *
 * param state:  MMI_MODEM_CALL_RESPONSE_STATE_CHANGE *
 * return  void
 */
void MMI_Modem_Call_Response_State_Change(MMI_Modem_Call_Response_State_Change_t * state)
{
    uint8_t i;

    if(0 == Hal_Pm_Get_State()) {
        for(i = 0; i < state->count; i++) {
            lv_mem_free(state->calls[i].number);
            lv_mem_free(state->calls[i].name);
        }
        lv_mem_free(state->calls);
        lv_mem_free(state);
        return;
    }

    mmi_msg_call_response_state_change_t * msg;

    msg = (mmi_msg_call_response_state_change_t *)lv_mem_alloc(sizeof(mmi_msg_call_response_state_change_t));

    msg->header.MsgId = MMI_MODEM_CALL_RESPONSE_STATE_CHANGE;
    msg->state = state;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * Indicates whether remote state is hold
 *
 * param simId:  MMI_MODEM_SIM_ID
 * param index:  Connection index
 * param IsHold: uint8_t ture for hold, and false for unhold
 * return  void
 */
void MMI_Modem_Call_Response_Remote_Hold(MMI_MODEM_SIM_ID SimId, int32_t Index, uint8_t IsHold)
{
    // todo
}

/**
 * Indicates the Mute control after every +CMUT?. (+CMUT:)
 * +CMUT: <n>
 * +CME ERROR: <err>
 *
 * param simId: MMI_MODEM_SIM_ID
 * param cmut:  MMI_MODEM_CALL_RESPONSE_CMUT *
 * return  void
 */
void MMI_Modem_Call_Response_Cmut(MMI_MODEM_SIM_ID simId, MMI_Modem_Call_Response_Cmut_t * cmut)
{
    if(0 == Hal_Pm_Get_State()) {
        lv_mem_free(cmut);
        return;
    }

    mmi_msg_call_response_cmut_t * msg = NULL;

    msg = (mmi_msg_call_response_cmut_t *)lv_mem_alloc(sizeof(mmi_msg_call_response_cmut_t));

    msg->header.MsgId = MMI_MODEM_CALL_RESPONSE_CMUT;
    msg->simid = simId;
    msg->cmut  = cmut;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * Indicates call fail cause.
 * param simId:  MMI_MODEM_SIM_ID
 * param ceer:  call fail cause
 * return  void
 */
void MMI_Modem_Call_Response_Ceer(MMI_MODEM_SIM_ID simId, char *ceer)
{
    if(0 == Hal_Pm_Get_State()) {
        Hal_Pm_WakeUp();
    } else {
        watch_wakeup_lcd(false);
    }

    mmi_msg_call_response_ceer_t * msg;

    msg = (mmi_msg_call_response_ceer_t *)lv_mem_alloc(sizeof(mmi_msg_call_response_ceer_t));

    msg->header.MsgId = MMI_MODEM_CALL_RESPONSE_CEER;
    msg->simid = simId;
    msg->ceer = ceer;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * indicate that PIN status changed
 * param (in) simId      :  MMI_MODEM_SIM_ID
 *       (in) PinReqType :  MMI_MODEM_PIN_STATUS_TYPE
 * return  void
 */
void  MMI_Modem_Pin_Status_Change_Ind(MMI_MODEM_SIM_ID SimId,
                                      MMI_MODEM_PIN_STATUS_TYPE PinReqType)
{
    if(0 == Hal_Pm_Get_State()) return;

    mmi_msg_pin_status_change_ind_t * msg;

    msg = (mmi_msg_pin_status_change_ind_t *)lv_mem_alloc(sizeof(mmi_msg_pin_status_change_ind_t));

    msg->header.MsgId = MMI_MODEM_PIN_STATUS_CHANGE_IND;
    msg->simid = SimId;
    msg->pinreqtype = PinReqType;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}
/**
 * plmn search confirm
 * param (in) PlmnSearchCnf:  MMI_Modem_Plmn_Search_Cnf_t
 * return void:
 */
void MMI_Modem_Plmn_Search_Cnf(MMI_Modem_Plmn_Search_Cnf_t * PlmnSearchCnf)
{
    // todo
}

/**
 * configure SS service call wait confirm
 * param (in) SimId  : MMI_MODEM_SIM_ID
 *       (in) Result : MMI_MODEM_RESULT
 * return void:
 */
void MMI_Modem_Call_Forward_Set_Cnf(MMI_MODEM_SIM_ID SimId, MMI_MODEM_RESULT Result)
{
#if 0
    if(MMI_MODEM_SUCCESS == Result) {
        if(MMI_MODEM_CALL_FORWARD_NO_CONDITION == CallForwardInfo->CallForwardType) {
            if(TRUE == CallForwardInfo->CallForwardOn) {
                g_ModemNwMng[SimId].NoConditionDivert.CallForwardOn = 1;
                memcpy(g_ModemNwMng[SimId].NoConditionDivert.DestNum,CallForwardInfo->DestNum,NV_CONTACTS_MAX_NUMBER_LEN);
            } else {
                g_ModemNwMng[SimId].NoConditionDivert.CallForwardOn = 0;
                memset(g_ModemNwMng[SimId].NoConditionDivert.DestNum,0,NV_CONTACTS_MAX_NUMBER_LEN);
            }
        } else if(MMI_MODEM_CALL_FORWARD_BUSY == CallForwardInfo->CallForwardType) {
            if(TRUE == CallForwardInfo->CallForwardOn) {
                g_ModemNwMng[SimId].BusyDivert.CallForwardOn = 1;
                memcpy(g_ModemNwMng[SimId].BusyDivert.DestNum,CallForwardInfo->DestNum,NV_CONTACTS_MAX_NUMBER_LEN);
            } else {
                g_ModemNwMng[SimId].BusyDivert.CallForwardOn = 0;
                memset(g_ModemNwMng[SimId].BusyDivert.DestNum,0,NV_CONTACTS_MAX_NUMBER_LEN);
            }
        } else if(MMI_MODEM_CALL_FORWARD_NOT_REACH == CallForwardInfo->CallForwardType) {
            if(TRUE == CallForwardInfo->CallForwardOn) {
                g_ModemNwMng[SimId].NotReachDivert.CallForwardOn = 1;
                memcpy(g_ModemNwMng[SimId].NotReachDivert.DestNum,CallForwardInfo->DestNum,NV_CONTACTS_MAX_NUMBER_LEN);
            } else {
                g_ModemNwMng[SimId].NotReachDivert.CallForwardOn = 0;
                memset(g_ModemNwMng[SimId].NotReachDivert.DestNum,0,NV_CONTACTS_MAX_NUMBER_LEN);
            }
        } else if(MMI_MODEM_CALL_FORWARD_NO_ANSWER == CallForwardInfo->CallForwardType) {
            if(TRUE == CallForwardInfo->CallForwardOn) {
                g_ModemNwMng[SimId].NoAnswerDivert.CallForwardOn = 1;
                memcpy(g_ModemNwMng[SimId].NoAnswerDivert.DestNum,CallForwardInfo->DestNum,NV_CONTACTS_MAX_NUMBER_LEN);
                g_ModemNwMng[SimId].NoAnswerDivert.NoAnswerDelay = CallForwardInfo->NoAnswerDelay;
            } else {
                g_ModemNwMng[SimId].NoAnswerDivert.CallForwardOn = 0;
                g_ModemNwMng[SimId].NoAnswerDivert.NoAnswerDelay = 20;
                memset(g_ModemNwMng[SimId].NoAnswerDivert.DestNum,0,NV_CONTACTS_MAX_NUMBER_LEN);
            }
        } else if(MMI_MODEM_CALL_FORWARD_CANCEL_All == CallForwardInfo->CallForwardType) {
            memset(&g_ModemNwMng[SimId].NoConditionDivert,0,sizeof(MMI_Modem_Call_Forward_Info_t));
            memset(&g_ModemNwMng[SimId].BusyDivert,0,sizeof(MMI_Modem_Call_Forward_Info_t));
            memset(&g_ModemNwMng[SimId].NotReachDivert,0,sizeof(MMI_Modem_Call_Forward_Info_t));
            memset(&g_ModemNwMng[SimId].NoAnswerDivert,0,sizeof(MMI_Modem_Call_Forward_Info_t));
            g_ModemNwMng[SimId].NoAnswerDivert.NoAnswerDelay = 20;
        }
    }
#endif
    printf("##interface## %s:Result is %d,SimId is %d\n", __FUNCTION__,Result,SimId);
    MMI_Modem_Call_Forward_Query_Req(SimId, MMI_MODEM_CALL_FORWARD_NO_CONDITION);
    MMI_Modem_Call_Forward_Query_Req(SimId, MMI_MODEM_CALL_FORWARD_BUSY);
    MMI_Modem_Call_Forward_Query_Req(SimId, MMI_MODEM_CALL_FORWARD_NOT_REACH);
    MMI_Modem_Call_Forward_Query_Req(SimId, MMI_MODEM_CALL_FORWARD_NO_ANSWER);
#if 0
    if(0 == Hal_Pm_Get_State()) {
        Hal_Pm_WakeUp();
    } else {
        watch_wakeup_lcd(false);
    }

    mmi_msg_call_forward_set_t * msg;

    msg = (mmi_msg_call_forward_set_t *)lv_mem_alloc(sizeof(mmi_msg_call_forward_set_t));

    msg->header.MsgId = MMI_MODEM_CALL_FORWARD_SET_CNF;
    msg->simid = SimId;
    msg->result = Result;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
#endif
}

/**
 * query SS service call wait confirm
 * param (in) SimId  : MMI_MODEM_SIM_ID
 * param (in) Result : MMI_MODEM_RESULT
 * param (in) CallForwardInfo : MMI_Modem_Call_Forward_Info_t(response of check status)
 * return void
 */
void MMI_Modem_Call_Forward_Query_Cnf(MMI_MODEM_SIM_ID SimId, MMI_MODEM_RESULT Result,
                                      MMI_Modem_Call_Forward_Info_t * CallForwardInfo)
{
    printf("##interface## %s:Result is %d,SimId is %d\n", __FUNCTION__,Result,SimId);
    if(MMI_MODEM_SUCCESS == Result) {
        printf("##interface## %s:CallForwardType is %d,CallForwardInfo->DestNum is %s\n", __FUNCTION__,CallForwardInfo->CallForwardType,CallForwardInfo->DestNum);
        if(MMI_MODEM_CALL_FORWARD_NO_CONDITION == CallForwardInfo->CallForwardType) {
            if(TRUE == CallForwardInfo->CallForwardOn) {
                g_ModemNwMng[SimId].NoConditionDivert.CallForwardOn = 1;
                memcpy(g_ModemNwMng[SimId].NoConditionDivert.DestNum,CallForwardInfo->DestNum,NV_CONTACTS_MAX_NUMBER_LEN);
            } else {
                g_ModemNwMng[SimId].NoConditionDivert.CallForwardOn = 0;
                memset(g_ModemNwMng[SimId].NoConditionDivert.DestNum,0,NV_CONTACTS_MAX_NUMBER_LEN);
            }
        } else if(MMI_MODEM_CALL_FORWARD_BUSY == CallForwardInfo->CallForwardType) {
            if(TRUE == CallForwardInfo->CallForwardOn) {
                g_ModemNwMng[SimId].BusyDivert.CallForwardOn = 1;
                memcpy(g_ModemNwMng[SimId].BusyDivert.DestNum,CallForwardInfo->DestNum,NV_CONTACTS_MAX_NUMBER_LEN);
            } else {
                g_ModemNwMng[SimId].BusyDivert.CallForwardOn = 0;
                memset(g_ModemNwMng[SimId].BusyDivert.DestNum,0,NV_CONTACTS_MAX_NUMBER_LEN);
            }
        } else if(MMI_MODEM_CALL_FORWARD_NOT_REACH == CallForwardInfo->CallForwardType) {
            if(TRUE == CallForwardInfo->CallForwardOn) {
                g_ModemNwMng[SimId].NotReachDivert.CallForwardOn = 1;
                memcpy(g_ModemNwMng[SimId].NotReachDivert.DestNum,CallForwardInfo->DestNum,NV_CONTACTS_MAX_NUMBER_LEN);
            } else {
                g_ModemNwMng[SimId].NotReachDivert.CallForwardOn = 0;
                memset(g_ModemNwMng[SimId].NotReachDivert.DestNum,0,NV_CONTACTS_MAX_NUMBER_LEN);
            }
        } else if(MMI_MODEM_CALL_FORWARD_NO_ANSWER == CallForwardInfo->CallForwardType) {
            if(TRUE == CallForwardInfo->CallForwardOn) {
                g_ModemNwMng[SimId].NoAnswerDivert.CallForwardOn = 1;
                memcpy(g_ModemNwMng[SimId].NoAnswerDivert.DestNum,CallForwardInfo->DestNum,NV_CONTACTS_MAX_NUMBER_LEN);
                g_ModemNwMng[SimId].NoAnswerDivert.NoAnswerDelay = CallForwardInfo->NoAnswerDelay;
            } else {
                g_ModemNwMng[SimId].NoAnswerDivert.CallForwardOn = 0;
                g_ModemNwMng[SimId].NoAnswerDivert.NoAnswerDelay = 20;
                memset(g_ModemNwMng[SimId].NoAnswerDivert.DestNum,0,NV_CONTACTS_MAX_NUMBER_LEN);
            }
            printf("##interface## %s:NoAnswerDelay is %d\n", __FUNCTION__,g_ModemNwMng[SimId].NoAnswerDivert.NoAnswerDelay);
        }
    }
    Hal_Mem_Free(CallForwardInfo);
#if 0
    if(0 == Hal_Pm_Get_State()) {
        Hal_Pm_WakeUp();
    } else {
        watch_wakeup_lcd(false);
    }

    mmi_msg_call_forward_query_t * msg;

    msg = (mmi_msg_call_forward_query_t *)lv_mem_alloc(sizeof(mmi_msg_call_forward_query_t));

    msg->header.MsgId = MMI_MODEM_CALL_FORWARD_QUERY_CNF;
    msg->simid = SimId;
    msg->result = Result;
    msg->call_forward_info = CallForwardInfo;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
#endif
}

/**
 * configure SS service call wait confirm
 * param (in) SimId : MMI_MODEM_SIM_ID
 * param (in) Result : MMI_MODEM_RESULT
 * return void:
 */
void MMI_Modem_Call_Wait_Set_Cnf(MMI_MODEM_SIM_ID SimId, MMI_MODEM_RESULT Result)
{
    printf("##interface## %s:Result is %d,SimId is %d\n", __FUNCTION__,Result,SimId);
    MMI_Modem_Call_Wait_Query_Req(SimId);
}

/**
 * query SS service call wait confirm
 * param (in) SimId : MMI_MODEM_SIM_ID
 * param (in) CallWaitOn : uint8_t
 * param (in) Result : MMI_MODEM_RESULT
 * return void
 */
void MMI_Modem_Call_Wait_Query_Cnf(MMI_MODEM_SIM_ID SimId, uint8_t CallWaitOn, MMI_MODEM_RESULT Result)
{
    printf("##interface## %s:Result is %d,SimId is %d,CallWaitOn is %d\n", __FUNCTION__,Result,SimId,CallWaitOn);
    if(MMI_MODEM_SUCCESS == Result) {
        if(TRUE == CallWaitOn) {
            g_ModemNwMng[SimId].CcwaOnOffFlg = 1;
        } else {
            g_ModemNwMng[SimId].CcwaOnOffFlg = 0;
        }
    }
}

/**
 * Signal bar indication
 * param (in) Bar:  MMI_MODEM_SIGNAL_BAR
 * return  void
 */
void MMI_Modem_Signal_Bar_Ind(MMI_MODEM_SIM_ID SimId, MMI_MODEM_SIGNAL_BAR Bar)
{
    if(0 == Hal_Pm_Get_State()) return;

    // mmi_msg_signal_bar_ind_t * msg;

    // msg = (mmi_msg_signal_bar_ind_t *)lv_mem_alloc(sizeof(mmi_msg_signal_bar_ind_t));

    // msg->header.MsgId = MMI_MODEM_SIGNAL_BAR_IND;
    // msg->simid = SimId;
    // msg->bar = Bar;

    // Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * Operator(short name) indicator reported when register at the first time
 * param (in) SimId: MMI_MODEM_SIM_ID
 * param (in) Operator: char*
 * return  void
 */
void MMI_Modem_Operator_Ind(MMI_MODEM_SIM_ID SimId, char * Operator, MMI_MODEM_PLMN_RAT Rat)
{
    if(0 == Hal_Pm_Get_State()) {
        lv_mem_free(Operator);
        return;
    }

    mmi_msg_operator_ind_t * msg;

    msg = (mmi_msg_operator_ind_t *)lv_mem_alloc(sizeof(mmi_msg_operator_ind_t));

    msg->header.MsgId = MMI_MODEM_OPERATOR_IND;
    msg->simid = SimId;
    msg->Operator = Operator;
    msg->rat = Rat;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * time auto-update indication
 * param (in) :
 * return  void
 */
void MMI_Modem_Time_Update_Ind(MMI_Modem_Time_Info_t * TimeInfo)
{
    if(0 == Hal_Pm_Get_State()) {
        lv_mem_free(TimeInfo);
        return;
    }

    mmi_msg_time_update_ind_t * msg;

    msg = (mmi_msg_time_update_ind_t *)lv_mem_alloc(sizeof(mmi_msg_time_update_ind_t));

    msg->header.MsgId = MMI_MODEM_TIME_UPDATE_IND;
    msg->TimeInfo = TimeInfo;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * SIM status indicator
 * param (in) SimId: MMI_MODEM_SIM_ID
 * param (in) SimPresent: uint8_t
 * return  void
 */
void MMI_Modem_Sim_Status_Ind(MMI_Modem_Sim_Status_t * SimStatus)
{
    if(0 == Hal_Pm_Get_State()) {
        lv_mem_free(SimStatus);
        return;
    }

    mmi_msg_sim_status_ind_t * msg;

    msg = (mmi_msg_sim_status_ind_t *)lv_mem_alloc(sizeof(mmi_msg_sim_status_ind_t));

    msg->header.MsgId = MMI_MODEM_SIM_STATUS_IND;
    msg->SimStatus = SimStatus;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * Response for getting phone book status
 * param (in) SimId: MMI_MODEM_SIM_ID
 * param (in) PhkStatus: MMI_Modem_Phonebook_Status*
 * return  void
 */
void MMI_Modem_Get_Phonebook_Status_Cnf(MMI_MODEM_SIM_ID SimId,
                                        MMI_Modem_Phonebook_Status * PhkStatus)
{
    if(0 == Hal_Pm_Get_State()) {
        return;
    }

    mmi_msg_get_phonebook_status_cnf_t * msg;

    msg = (mmi_msg_get_phonebook_status_cnf_t *)lv_mem_alloc(sizeof(mmi_msg_get_phonebook_status_cnf_t));

    msg->header.MsgId = MMI_MODEM_GET_PHONEBOOK_STATUS_CNF;
    msg->total = PhkStatus->total;
    msg->used = PhkStatus->used;
    msg->firstIndex = PhkStatus->firstIndex;
    Hal_Mem_Free(PhkStatus);

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * Response for updating contact into phone book
 * param (in) SimId: MMI_MODEM_SIM_ID
 * param (in) WrittenIndex: uint16_t
 * return  void
 */
void MMI_Modem_Write_Phonebook_Cnf(MMI_MODEM_SIM_ID SimId, uint16_t WrittenIndex)
{
    if(0 == Hal_Pm_Get_State()) {
        return;
    }

    mmi_msg_write_phonebook_cnf_t * msg;

    msg = (mmi_msg_write_phonebook_cnf_t *)lv_mem_alloc(sizeof(mmi_msg_write_phonebook_cnf_t));

    msg->header.MsgId = MMI_MODEM_WRITE_PHONEBOOK_CNF;
    msg->writtenindex = WrittenIndex;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * Response for reading contacts from phone book
 * param (in) SimId: MMI_MODEM_SIM_ID
 * param (in) Contact: MMI_Modem_Contact*
 * param (in) Number: uint16_t
 * param (in) End: BOOL
 * return  void
 */
void MMI_Modem_Read_Phonebook_Cnf(MMI_MODEM_SIM_ID SimId,
                                  MMI_Modem_Contact * Contact,
                                  uint16_t Number,
                                  BOOL End)
{
    if(0 == Hal_Pm_Get_State()) {
        return;
    }

    mmi_msg_read_phonebook_cnf_t * msg;

    msg = (mmi_msg_read_phonebook_cnf_t *)lv_mem_alloc(sizeof(mmi_msg_read_phonebook_cnf_t));

    msg->header.MsgId = MMI_MODEM_READ_PHONEBOOK_CNF;
    msg->contact = Contact;
    msg->number = Number;
    msg->end = End;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * Indicate When phone book has been loaded by CP
 * param (in) SimId: MMI_MODEM_SIM_ID
 * return  void
 */
void MMI_Modem_Phonebook_Init_Ind(MMI_MODEM_SIM_ID SimId)
{
    if(0 == Hal_Pm_Get_State()) {
        return;
    }

    mmi_msg_phonebook_init_ind_t * msg;

    msg = (mmi_msg_phonebook_init_ind_t *)lv_mem_alloc(sizeof(mmi_msg_phonebook_init_ind_t));

    msg->header.MsgId = MMI_MODEM_PHONEBOOK_INIT_IND;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * send new sms cnf
 * param (in) pSendSmsCnf: MMI_Modem_Send_Sms_Cnf_t
 * return  void
 */
void MMI_Modem_Send_Sms_Cnf(MMI_Modem_Send_Sms_Cnf_t * pSendSmsCnf)
{
    if(0 == Hal_Pm_Get_State()) {
        lv_mem_free(pSendSmsCnf);
        return;
    }

    mmi_msg_send_sms_cnf_t * msg;

    msg = (mmi_msg_send_sms_cnf_t *)lv_mem_alloc(sizeof(mmi_msg_send_sms_cnf_t));

    msg->header.MsgId = MMI_MODEM_SEND_SMS_CNF;
    msg->psendsmscnf = pSendSmsCnf;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * delete sms cnf
 * param (in) Result:MMI_MODEM_SMS_RESULT_TYPE
 * return  void
 */
void MMI_Modem_Delete_Sms_Cnf(MMI_MODEM_SMS_RESULT_TYPE Result)
{
    // todo
}

/**
 * read sms info cnf
 * param (in) pReadSmsInfoCnf: MMI_Modem_Read_Sms_Info_Cnf_t
 * return  void
 */
void MMI_Modem_Read_Sms_Info_Cnf(MMI_Modem_Read_Sms_Info_Cnf_t * pReadSmsInfoCnf)
{
    // todo
}

/**
 * read sms detail on sim cnf
 * param (in) pReadSmsCnf: MMI_Modem_Read_Sms_Detail_On_Sim_Cnf_t
 * return  void
 */
void MMI_Modem_Read_Sms_Detail_On_Sim_Cnf(
    MMI_Modem_Read_Sms_Detail_On_Sim_Cnf_t * pReadSmsCnf)
{
    if(0 == Hal_Pm_Get_State()) {
        lv_mem_free(pReadSmsCnf);
        return;
    }

    mmi_msg_read_sms_detail_on_sim_cnf_t * msg;

    msg = (mmi_msg_read_sms_detail_on_sim_cnf_t *)lv_mem_alloc(sizeof(mmi_msg_read_sms_detail_on_sim_cnf_t));

    msg->header.MsgId = MMI_MODEM_READ_SMS_DETAIL_ON_SIM_CNF;
    msg->preadsmscnf = pReadSmsCnf;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * get sms centre number cnf
 * param (in) pGetSmscCnf: MMI_Modem_Get_Smsc_Cnf_t
 * return  void
 */
void MMI_Modem_Get_Smsc_Cnf(MMI_Modem_Get_Smsc_Cnf_t * pGetSmscCnf)
{
    if(0 == Hal_Pm_Get_State()) {
        lv_mem_free(pGetSmscCnf);
        return;
    }

    mmi_msg_get_smsc_cnf_t * msg;

    msg = (mmi_msg_get_smsc_cnf_t *)lv_mem_alloc(sizeof(mmi_msg_get_smsc_cnf_t));

    msg->header.MsgId = MMI_MODEM_GET_SMSC_CNF;
    msg->pgetsmsccnf = pGetSmscCnf;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * set sms centre number cnf
 * param (in) Result:MMI_MODEM_SMS_RESULT_TYPE
 * return  void
 */
void MMI_Modem_Set_Smsc_Cnf(MMI_MODEM_SMS_RESULT_TYPE Result)
{
    // todo
}

/**
 * set delivery report flg cnf
 * param (in) Result:MMI_MODEM_SMS_RESULT_TYPE
 * return  void
 */
void MMI_Modem_Set_Delivery_Rep_Cnf(MMI_MODEM_SMS_RESULT_TYPE Result)
{
    // todo
}

/**
 * report new sms ind
 * param (in) pRepNewSms:MMI_Modem_Report_New_Sms_Ind_t
 * return  void
 */
void MMI_Modem_Rep_New_Sms_Ind(MMI_Modem_Report_New_Sms_Ind_t * pRepNewSms)
{
    if(0 == Hal_Pm_Get_State()) {
        lv_mem_free(pRepNewSms);
        return;
    }

    mmi_msg_rep_new_sms_ind_t * msg;

    msg = (mmi_msg_rep_new_sms_ind_t *)lv_mem_alloc(sizeof(mmi_msg_rep_new_sms_ind_t));

    msg->header.MsgId = MMI_MODEM_REP_NEW_SMS_IND;
    msg->prepnewsms = pRepNewSms;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * report new status report ind
 * param (in) pRepNewStsRep:MMI_Modem_Response_Sms_Status_Rep_Ind_t
 * return  void
 */
void MMI_Modem_Sms_Status_Rep_Ind(MMI_Modem_Response_Sms_Status_Rep_Ind_t * pSmsStsRep)
{
    // todo
}

/**
 * report SMS storage status of SIM
 * param (in) pRepSimSmsStaInd: MMI_Modem_SIM_SMS_Storage_Status_Ind
 * return  void
 */
void MMI_Modem_SIM_SMS_Storage_Status_Ind(
    MMI_Modem_SIM_SMS_Storage_Status_Ind_t * pRepSimSmsStaInd)
{
    // todo
}

/**
 * send Ussd cnf
 * param (in) pSendUssdCnf: MMI_Modem_Send_Ussd_Cnf_t
 * return  void
 */
void MMI_Modem_Send_Ussd_Cnf(MMI_Modem_Send_Ussd_Cnf_t * pSendUssdCnf)
{
    // todo
}

/**
 * init modem adaptor
 * param (in) void
 * return  void
 */
void watch_modem_adp_init_req(void)
{
    MMI_ModemAdp_Init_Req(1);
}

/**
 * report the lte cells information in engineer mode
 * param (in) MMI_Modem_Lte_Cells_t  *ltecells
 * return  void
 */
void MMI_Modem_Lte_Cells_Ind(MMI_Modem_Lte_Cells_t * ltecells)
{
    if(0  == Hal_Pm_Get_State()) {
        lv_mem_free(ltecells);
        return;
    }

    mmi_msg_lte_cells_info_t * msg;

    msg = (mmi_msg_lte_cells_info_t *)lv_mem_alloc(sizeof(mmi_msg_lte_cells_info_t));

    msg->header.MsgId = MMI_MODEM_LTE_CELLS_INFO;
    msg->pltecells = ltecells;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * report the gsm cells information in engineer mode
 * param (in) MMI_Modem_Lte_Cells_t  *ltecells
 * return  void
 */
void MMI_Modem_Gsm_Cells_Ind(MMI_Modem_Gsm_Cells_t * gsmcells)
{
    if(0  == Hal_Pm_Get_State()) {
        lv_mem_free(gsmcells);
        return;
    }

    mmi_msg_gsm_cells_info_t * msg;

    msg = (mmi_msg_gsm_cells_info_t *)lv_mem_alloc(sizeof(mmi_msg_gsm_cells_info_t));

    msg->header.MsgId = MMI_MODEM_GSM_CELLS_INFO;
    msg->pgsmcells = gsmcells;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}
/**
 * get cell info req
 * param (in) void
 * return  void
 */
void watch_modem_adp_get_cell_info_req(void)
{
    MMI_ModemAdp_Get_Cell_Info_Req();
}

uint8_t watch_modem_adp_get_ril_ready_state_req(void)
{
    return(MMI_ModemAdp_Get_Ril_Ready_state());
}

void watch_modem_call_forward_set_req(MMI_Modem_Call_Forward_Info_t * CallForwardInfo)
{
    MMI_Modem_Call_Forward_Set_Req(modem_sim_id, CallForwardInfo);
}

MMI_Modem_Call_Forward_Info_t * watch_modem_call_forward_query_req(MMI_MODEM_CALL_FORWARD_TYPE CallForwardType)
{
    return MMI_Modem_Call_Forward_Get_Req(modem_sim_id,CallForwardType);
}

void watch_modem_call_wait_set_req(uint8_t callwait_onoff_flg)
{//0:off,1:on
    if(callwait_onoff_flg) {
        MMI_Modem_Call_Wait_Set_Req(modem_sim_id, TRUE);
    } else {
        MMI_Modem_Call_Wait_Set_Req(modem_sim_id, FALSE);
    }
}

uint8_t watch_modem_call_wait_query_req(void)
{//0:off,1:on
    return MMI_Modem_Call_Wait_Get_Req(modem_sim_id);
}

/**
 * get calibration info req
 * param (in) void
 * return  void
 */
void watch_modem_adp_get_calibration_info_req(void)
{
    MMI_ModemAdp_Get_Calibration_Info_Req(modem_sim_id);
}

/**
 * get sn info req
 * param (in) void
 * return  void
 */
void watch_modem_adp_get_sn_info_req(void)
{
    MMI_ModemAdp_Get_Sn_Info_Req(modem_sim_id);
}

void app_adp_get_radio_power_status_req(app_adp_radio_power_cb cb)
{
    MMI_Modem_Radio_Power_Status_Req(modem_sim_id, cb);
}

void app_adp_radio_power_req(uint8_t onoff)
{
    printf("%s: onoff %d\n", __FUNCTION__, onoff);

    if(1 == onoff) {
        watch_modem_power_up_req();
    } else {
        watch_modem_power_off_req();
    }
}

/**
 * report the nw ims vops status
 * param (in) MMI_MODEM_SIM_ID simId
 * param (in) uint8_t display_sendsms_flg //0:display not send sms,1:display send sms
 * return  void
 */
void MMI_Modem_Ims_Vops_Ind(MMI_MODEM_SIM_ID simId,uint8_t display_sendsms_flg)
{
    if(0 == Hal_Pm_Get_State()) {
        Hal_Pm_WakeUp();
    } else {
        watch_wakeup_lcd(true);
    }

    mmi_msg_ims_vops_ind_t * msg;

    msg = (mmi_msg_ims_vops_ind_t *)lv_mem_alloc(sizeof(mmi_msg_ims_vops_ind_t));

    msg->header.MsgId = MMI_MODEM_IMS_VOPS_IND;
    msg->display_sendsms_flg = display_sendsms_flg;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

uint8_t app_adp_get_roaming_stat_req(void)
{
    return(MMI_Modem_Get_Roaming_Stat_Req(modem_sim_id));
}

/**
 * report the calibration result in engineer mode
 * param (in) ucResult: uint8_t
 * return  void
 */
void MMI_Modem_Cali_Rslt_Ind(UINT8 ucResult)
{
    if(0 == Hal_Pm_Get_State()) {
        Hal_Pm_WakeUp();
    } else {
        watch_wakeup_lcd(false);
    }

    mmi_msg_cali_rslt_ind_t * msg = NULL;

    msg = (mmi_msg_cali_rslt_ind_t *)lv_mem_alloc(sizeof(mmi_msg_cali_rslt_ind_t));

    msg->header.MsgId = MMI_MODEM_CALI_RESULT_IND;
    msg->result = ucResult;

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * report the SN information in engineer mode
 * param (in) pSn: INT8*
 *            ucResult: UINT8
 * return  void
 */
void MMI_Modem_Sn_Info_Ind(INT8 * pSn)
{
    if(0 == Hal_Pm_Get_State()) {
        Hal_Pm_WakeUp();
    } else {
        watch_wakeup_lcd(false);
    }

    mmi_msg_sn_info_ind_t * msg = NULL;
    uint8_t tmplen = 0;

    msg = (mmi_msg_sn_info_ind_t *)lv_mem_alloc(sizeof(mmi_msg_sn_info_ind_t));
    memset(msg, 0, sizeof(mmi_msg_sn_info_ind_t));

    msg->header.MsgId = MMI_MODEM_SN_INFO_IND;
    if(NULL != pSn) {
        tmplen = strlen(pSn);
        msg->psn = (char *)lv_mem_alloc(tmplen + 1);
        memset(msg->psn, 0, (tmplen + 1));
        memcpy(msg->psn, pSn, tmplen);
        lv_mem_free(pSn);
    } else {
        printf("%s,SN is null\n", __FUNCTION__);
    }

    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

#if USE_LV_WATCH_VOIP_ADAPTOR
/**
 *
 * This message is sent to the called mobile station
 * to indicate an incoming video call
 * param para:  MMI_Modem_Video_Call_Response_Incoming_t *
 * return  void
 */
void MMI_Modem_Video_Call_Response_Incoming(MMI_Modem_Video_Call_Response_Incoming_t * Response)
{
    if(0 == Hal_Pm_Get_State()) {
        watch_disable_wakeup_lcd();
        Hal_Pm_WakeUp();
    }

    mmi_msg_video_call_response_incoming_t * msg;

    msg = (mmi_msg_video_call_response_incoming_t *)Hal_Mem_Alloc(sizeof(mmi_msg_video_call_response_incoming_t));

    memset(msg, 0, sizeof(mmi_msg_video_call_response_incoming_t));
    msg->header.MsgId = MMI_MODEM_VIDEO_CALL_RESPONSE_INCOMING;
    msg->incoming = Response;
    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 *
 * This message is sent to the UI for common response
 * param simId:  MMI_MODEM_SIM_ID
 * return  void
 */
void MMI_Modem_Video_Call_Common_Response(uint16_t MsgId)
{
    mmi_msg_video_call_common_response_t * msg;

    msg = (mmi_msg_video_call_common_response_t *)lv_mem_alloc(sizeof(mmi_msg_video_call_common_response_t));
    msg->header.MsgId = MsgId;
    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 *
 * This message is sent to the UI for common response
 * param simId:  MMI_MODEM_SIM_ID
 * return  void
 */
void MMI_Modem_Video_Call_Response_Test_Voice_Mo_Req(char * uri)
{
    mmi_msg_video_call_response_test_mo_t * msg;

    msg = (mmi_msg_video_call_response_test_mo_t *)lv_mem_alloc(sizeof(mmi_msg_video_call_response_test_mo_t));
    msg->header.MsgId = MMI_MODEM_VIDEO_CALL_RESPONSE_TEST_VOICE_MO_REQ;
    strcpy(msg->uri, uri);
    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 *
 * This message is sent to the UI for common response
 * param simId:  MMI_MODEM_SIM_ID
 * return  void
 */
void MMI_Modem_Video_Call_Response_Test_Video_Mo_Req(char * uri)
{
    mmi_msg_video_call_response_test_mo_t * msg;

    msg = (mmi_msg_video_call_response_test_mo_t *)lv_mem_alloc(sizeof(mmi_msg_video_call_response_test_mo_t));
    msg->header.MsgId = MMI_MODEM_VIDEO_CALL_RESPONSE_TEST_VIDEO_MO_REQ;
    strcpy(msg->uri, uri);
    Hal_Send_Message((TASK_ID)gui_task_id, (void *)msg);
}

/**
 * This is used to start  video call
 * param calltype: MODEM_VIDEO_CALL_TYPE
 * param pContactUri: char*
 * return  UINT32
 */
int32_t wach_modem_video_call_dial_req(MODEM_VIDEO_CALL_TYPE calltype, char * pContactUri)
{
    printf("#interface %s\n", __FUNCTION__);
    MMI_Modem_Video_Call_Dial_Req(calltype, pContactUri);

    return 1;
}

/**
 * This is used to control video call action
 * param op: UINT16
 * param vidType: UINT16
 * return  UINT32
 */
uint32_t watch_modem_video_call_action_req(MODEM_VIDEO_CALL_ACTION op,
        MODEM_VIDEO_CALL_BARESIPVIDMODE vidType)
{
    printf("#interface %s op %d vidtype %d\n", __FUNCTION__, op, vidType);
    MMI_Modem_Video_Call_Action_Req(op, vidType);
    return 1;
}

/**
 * This is used to set local preview
 * param stat:
 * return  void
 */
void watch_modem_video_call_set_local_preview_req(bool localpreview)
{
    MMI_Modem_Video_Call_Set_Local_Preview_Req(localpreview);
}

/**
 * This is used to get the reg state of video call.
 * param stat:  reg status
 * return  void
 */
uint8_t watch_modem_video_call_get_reg_stat_req(void)
{
    return(MMI_Modem_Video_Call_Get_Reg_Stat_Req());
}
#endif //#if USE_LV_WATCH_VOIP_ADAPTOR
#else
MMI_MODEM_SIM_ID watch_modem_get_sim_id(void)
{
    return MMI_MODEM_SIM_1;
}

void watch_modem_set_sim_id(MMI_MODEM_SIM_ID sim_id)
{

}

void watch_modem_switch_to_sim(MMI_MODEM_SIM_ID sim_to)
{

}

void watch_modem_set_connection_switch(BOOL onOff)
{

}

BOOL watch_modem_get_connection_switch(void)
{
    return 1;
}

void watch_modem_set_data_roaming(BOOL OnOff)
{

}

BOOL watch_modem_get_data_roaming(void)
{
    return 1;
}

int watch_modem_get_default_apn_name(char *name, int name_len)
{
    strncpy(name, "cmnet", name_len);
    return 0;
}

int watch_modem_get_default_ip_type(void)
{
    return 1;   //IPV4
}

void watch_modem_set_apn_info(MMI_Modem_Apn_Info_t *apnInfo)
{

}

void watch_modem_reset_apn(void)
{

}

void watch_modem_config_apn(char *apn, UINT8 ipType)
{

}

void watch_modem_open_volte(void)
{

}

uint8_t get_wifi(void)
{
    /*wifi: 0/1/2/3/4*/
    uint8_t wifi = 4;

    return wifi;
}

void watch_modem_get_imei_req(char * imei)
{
    static char tmp_imei[16] = "352099001761480";
    memcpy(imei, tmp_imei, 16);
}

void watch_modem_get_baseband_ver_req(char * baseband_ver)
{
    static char tmp_baseband_ver[50] = "SDK_1.011.053X";
    memcpy(baseband_ver, tmp_baseband_ver, 50);
}

void  watch_modem_get_imsi_req(char * imsi)
{
    static char tmp_imsi[16] = "987654321098765";
    memcpy(imsi, tmp_imsi, 16);
}

void  watch_modem_sim_soft_reset_req(void)
{

}

uint8_t watch_modem_sim_present_check_req(void)
{
    return(1);
}

MMI_MODEM_SIGNAL_BAR watch_modem_get_signal_bar_req(void)
{
    return(MMI_MODEM_SIGNAL_BAR_5);
}

uint8_t watch_modem_voice_registration_state_req(void)
{
    return(MMI_MODEM_VOICE_NORMAL);
}

void watch_modem_get_operator_req(MMI_MODEM_PLMN_RAT * Rat)
{
    *Rat = MMI_MODEM_PLMN_RAT_LTE;
}

uint8_t watch_modem_get_ims_reg_state_req(void)
{
    return(1);
}

uint8_t watch_modem_get_gsm_reg_state_req(void)
{
    return(1);
}

uint8_t watch_modem_get_umts_reg_state_req(void)
{
    return(2);
}

void watch_modem_call_request_dial(char * number, MMI_MODEM_CALL_SERVICE_TYPE servicetype)
{

}

void watch_modem_call_request_hangup(int32_t index)
{

}

void watch_modem_call_request_hangup_foreground_resume_background(void)
{

}

void watch_modem_call_request_switch_waiting_or_hold_and_active(void)
{

}

void watch_modem_call_request_udub(void)
{

}

void watch_modem_call_request_answer(void)
{

}

void watch_modem_call_response_clip_auto(int32_t index, MMI_Modem_Call_Response_Clip_t *clip)
{

}

void watch_modem_signal_bar_ind(MMI_MODEM_SIGNAL_BAR Bar)
{

}
void watch_modem_sim_status_ind(MMI_Modem_Sim_Status_t * SimStatus)
{

}

void watch_modem_read_sms_detail_on_sim_cnf(MMI_Modem_Read_Sms_Detail_On_Sim_Cnf_t * pReadSmsCnf)
{

}

void watch_modem_send_sms_cnf(MMI_Modem_Send_Sms_Cnf_t * pSendSmsCnf)
{

}

void watch_modem_operator_ind(MMI_MODEM_PLMN_RAT Rat)
{
}

void watch_modem_rep_new_sms_ind(MMI_Modem_Report_New_Sms_Ind_t * pRepNewSms)
{

}

void watch_modem_pin_status_change_ind(MMI_MODEM_PIN_STATUS_TYPE pinreqtype)
{

}

uint8_t watch_modem_request_enter_sim_pin(MMI_MODEM_PIN_TYPE pintype,char *pin)
{
    (void)pintype;

    return MMI_MODEM_PIN_CHECK_OK;
}

uint8_t watch_modem_change_sim_pin(MMI_MODEM_PIN_TYPE pintype,char *pin,char *oldpin)
{
    (void)pintype;

    return MMI_MODEM_PIN_CHECK_OK;
}

void watch_modem_query_pin_lock_info(MMI_MODEM_PIN_TYPE pintype,MMI_Modem_Query_Pin_Lock_Info_t *pinlockinfo)
{
    (void)pintype;

    pinlockinfo->PinEnable = false;
    pinlockinfo->RetriesLeft = 3;
}

uint8_t watch_modem_enable_or_disable_pin_lock(MMI_MODEM_PIN_TYPE pintype,uint8_t pinenable,char *pin)
{
    (void)pintype;

    return 1;
}

void watch_modem_adp_init_req(void)
{

}

void watch_modem_power_up_req(void)
{

}

void watch_modem_power_off_req(void)
{

}

void watch_modem_set_band_req(uint8_t bandmode, uint8_t gsmband, uint16_t ltebandh, uint32_t ltebandl)
{
}

void watch_modem_adp_get_cell_info_req(void)
{

}

uint8_t watch_modem_adp_get_ril_ready_state_req(void)
{
    return 1;
}

void watch_modem_call_forward_set_req(MMI_Modem_Call_Forward_Info_t * CallForwardInfo)
{
}

MMI_Modem_Call_Forward_Info_t CallForwardInfo;
MMI_Modem_Call_Forward_Info_t * watch_modem_call_forward_query_req(MMI_MODEM_CALL_FORWARD_TYPE CallForwardType)
{
    memset(&CallForwardInfo,0,sizeof(MMI_Modem_Call_Forward_Info_t));
    CallForwardInfo.NoAnswerDelay = 20;
    return &CallForwardInfo;
}

void watch_modem_call_wait_set_req(uint8_t callwait_onoff_flg)
{
}

uint8_t watch_modem_call_wait_query_req(void)
{
    return 1;
}

void app_adp_get_radio_power_status_req(app_adp_radio_power_cb cb)
{

}

void app_adp_radio_power_req(uint8_t onoff)
{

}

uint8_t app_adp_get_roaming_stat_req(void)
{
    return(0);
}

void watch_modem_adp_get_calibration_info_req(void)
{
}

void watch_modem_adp_get_sn_info_req(void)
{
}

static uint8_t volte_state = 1;
uint8_t MMI_Modem_Get_Volte_State_Req(MMI_MODEM_SIM_ID SimId)
{
    return volte_state;
}

void watch_modem_set_volte_state_req(uint8_t state)
{
    volte_state = state;
}

#if USE_LV_WATCH_VOIP_ADAPTOR
int32_t wach_modem_video_call_dial_req(MODEM_VIDEO_CALL_TYPE calltype, char * pContactUri)
{
    return 1;
}

uint32_t watch_modem_video_call_action_req(MODEM_VIDEO_CALL_ACTION op,
        MODEM_VIDEO_CALL_BARESIPVIDMODE vidType)
{
    return 1;
}

void watch_modem_video_call_set_local_preview_req(bool localpreview)
{
}

uint8_t watch_modem_video_call_get_reg_stat_req(void)
{
    return(MODEM_VIDEO_CALL_REG_OK);
}
#endif //#if USE_LV_WATCH_VOIP_ADAPTOR
#endif /*USE_LV_WATCH_MODEM_ADAPTOR*/

void app_adp_get_imei_req(char * imei)
{
    watch_modem_get_imei_req(imei);
}

void app_adp_get_imsi_req(char * imsi)
{
    watch_modem_get_imsi_req(imsi);
}
